package com.timepies.database;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;

import android.os.AsyncTask;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import com.timepies.domain.Timepie;

public class MongoDao {

	private static final String API_KEY = "lVHibmvvIG3-A0A4RZxh7q00F1635qs3";
	private static final String MONGODB_NAME = "bigdata";
	private static final String MONGODB_COLLECTION = "docs101";

	public String getDatabaseName() {
		return MONGODB_NAME;
	}

	public String getApiKey() {
		return API_KEY;
	}

	public String getBaseUrl() {
		return "https://api.mongolab.com/api/1/databases/" + getDatabaseName()
				+ "/collections/";
	}

	public String docApiKeyUrl() {
		return "?apiKey=" + getApiKey();
	}

	public String documentRequest() {
		return MONGODB_COLLECTION;
	}

	public String buildContactsSaveURL() {
		return getBaseUrl() + documentRequest() + docApiKeyUrl();
	}

	public String buildContactsDetailURL(String id) {
		return getBaseUrl() + documentRequest() + "/" + id + docApiKeyUrl();
	}

	public void saveAsync(Object pie) {
		SaveAsyncTask save = new SaveAsyncTask();
		save.execute(pie);
	}

	public void deleteAsync(Object pie) {
		DeleteAsyncTask delete = new DeleteAsyncTask();
		delete.execute(pie);
	}

	public List<Timepie> getList() {
		GetContactsAsyncTask read = new GetContactsAsyncTask();
		try {
			return read.execute().get();
		} catch (Exception e) {
			Log.e(toString(), e.getMessage());
			return new ArrayList<Timepie>();
		}

	}

	public static boolean isFake(String testo) {
		float length = testo.length(), vowels = 0, digits = 0, blanks = 0, cons = 0;

		if (testo == null || length < 4)
			return true;

		char ch;
		for (int i = 0; i < length; i++) {
			ch = testo.charAt(i);

			if ("AEIOUaeiou".contains(ch + ""))
				vowels++;
			else if (Character.isDigit(ch))
				digits++;
			else if (Character.isWhitespace(ch))
				blanks++;
			else
				cons++;
		}
		System.out.println(testo + "  length" + length + " vowels" + vowels
				+ " digits" + digits + " blanks" + blanks + " cons" + cons);
		if (cons / length > 0.8 || vowels / length > 0.8
				|| (vowels == 0 && cons != 0))
			return true;
		return false;
	}
}

class GetContactsAsyncTask extends AsyncTask<Timepie, Void, List<Timepie>> {
	private static String server_output = null;
	private static String temp_output = null;
	private ArrayList<Timepie> list = null;

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
	}

	@Override
	protected List<Timepie> doInBackground(Timepie... arg0) {

		if (list != null && list.size() != 0)
			return list;

		try {

			MongoDao dao = new MongoDao();
			Log.d(toString(), dao.buildContactsSaveURL());
			URL url = new URL(dao.buildContactsSaveURL());
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Accept", "application/json");

			if (conn.getResponseCode() != 200) {
				throw new RuntimeException("Failed : HTTP error code : "
						+ conn.getResponseCode());
			}

			BufferedReader br = new BufferedReader(new InputStreamReader(
					(conn.getInputStream())));

			while ((temp_output = br.readLine()) != null)
				server_output = temp_output;

			list = new Gson().fromJson(server_output,
					new TypeToken<List<Timepie>>() {
					}.getType());

			try {
				String[] ids = new String[list.size()];
				JSONArray jsonArray = new JSONArray(server_output);

				for (int i = 0; i < jsonArray.length(); i++)
					ids[i] = jsonArray.getJSONObject(i).getJSONObject("_id")
							.get("$oid").toString();

				Object[] array = list.toArray();
				for (int i = 0; i < array.length; i++)
					((Timepie) array[i]).setJsonId(ids[i]);

			} catch (Exception e) {
			}

			return (list != null && list.size() != 0) ? list
					: new ArrayList<Timepie>();

		} catch (Exception e) {
			Log.d(toString(), e.getMessage());
			return new ArrayList<Timepie>();
		}

	}
}

class SaveAsyncTask extends AsyncTask<Object, Void, Boolean> {

	@Override
	protected Boolean doInBackground(Object... arg0) {
		try {
			Object contact = arg0[0];

			MongoDao dao = new MongoDao();

			HttpClient httpClient = new DefaultHttpClient();
			HttpPost request = new HttpPost(dao.buildContactsSaveURL());

			JsonElement json = new Gson().toJsonTree(contact);
			StringEntity params = new StringEntity(json.toString());
			request.addHeader("content-type", "application/json");
			request.setEntity(params);
			HttpResponse response = httpClient.execute(request);

			if (response.getStatusLine().getStatusCode() < 205) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			Log.d(toString(), e.getMessage());
			return false;
		}
	}

}

class DeleteAsyncTask extends AsyncTask<Object, Void, Void> {

	@Override
	protected Void doInBackground(Object... pieArray) {
		HttpURLConnection conn = null;
		try {
			MongoDao dao = new MongoDao();
			String id = ((Timepie) pieArray[0]).getJsonId();
			String link = dao.buildContactsDetailURL(id);
			Log.d(toString(), link);
			URL url = new URL(link);
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			conn.setRequestMethod("DELETE");
			Log.d(toString(), "CODE " + conn.getResponseCode());

		} catch (Exception e) {
			Log.d(toString(), e.getMessage());
		} finally {
			if (conn != null)
				conn.disconnect();

		}
		return null;

	}

}